Skip to content

V2#264

Open
vishnu-deepsource wants to merge 80 commits intomasterfrom
v2
Open

V2#264
vishnu-deepsource wants to merge 80 commits intomasterfrom
v2

Conversation

@vishnu-deepsource
Copy link
Contributor

No description provided.

vishnu-deepsource and others added 7 commits January 28, 2026 15:17
Move utility packages from root `utils/` and `configvalidator/` into
organized `internal/` subdirectories:
- utils/prompt.go → internal/cli/prompt/
- utils/colors.go → internal/cli/style/
- utils/cmd_validator.go → internal/cli/args/
- utils/fetch_oidc_token.go → internal/oidc/
- utils/remote_resolver.go → internal/vcs/
- utils/fetch_remote.go → internal/vcs/remotes.go
- configvalidator/* → internal/configvalidator/
- utils/fetch_analyzers_transformers.go → internal/configdata/

Add shell completion support via internal/cli/completion package.

Update all import paths across commands and services to reflect new
structure. This improves code organization and follows Go's internal
package conventions for better encapsulation.
- Add new `auth whoami` command to display authenticated user info
- Add new `issues browse` command for opening issues in browser
- Add GetViewer API method to fetch authenticated user details
- Refactor output messages to use pterm.Print* instead of pterm.Info
  for consistency across auth, config, issues, and repo commands
- Update dependencies (pterm, testify, bubbletea, lipgloss)
- Add `runs list` command to display analysis runs for a repository
- Add `runs issues` command to show issues for a specific run
- Add GetAnalysisRuns and GetRunIssues API methods to client
- Add GraphQL schema and queries for runs and run issues
- Refactor whoami command to use boxed output format
- Remove issues browse command
- Add runs domain types and query helpers
Update all Go dependencies to their latest versions including:
- github.com/spf13/cobra: v1.5.0 → v1.10.2
- github.com/spf13/viper: v1.7.1 → v1.21.0
- github.com/getsentry/sentry-go: v0.6.0 → v0.41.0
- github.com/stretchr/testify: v1.8.4 → v1.11.1
- github.com/fatih/color: v1.12.0 → v1.18.0
- github.com/google/go-cmp: v0.5.5 → v0.6.0

Also includes improvements to issues display:
- Add terminal width-aware table rendering with column wrapping
- Improve issue location formatting (single line vs range)
- Add color-coded severity formatting
- Add JSON export capability for run issues with --json and --output-file flags
Add support for filtering issues by analyzer, category, severity, code, and path.
Filters can be specified multiple times to match any of the provided values.

New flags:
- --analyzer: filter by analyzer shortcode
- --category: filter by issue category
- --severity: filter by severity level
- --code: filter by issue code
- --path: filter by file path (supports partial matching)

Also refactor runs command to accept commit-oid argument and wire up
issue flags via AddRunIssueFlags for better flag reusability.
- Replace Makefile with justfile, add VERSION file for version tracking
- Replace goreleaser release pipeline with build-and-deploy workflow
- Add install script template
- Move version/ package to buildinfo/
- Swap DataDog/zstd (cgo) for klauspost/compress/zstd (pure Go)
- Replace deprecated io/ioutil usage with os and io
- Bump Go version to 1.25 in CI
- Update SARIF schema URL to official OASIS source
- Add TCP readiness check for mock server in tests
- Update README with auth docs and current command list
- Drop config generate/validate commands and supporting packages
- Drop issues list command and related services
- Remove configvalidator, configdata, and issues service packages
- Update root command registrations and dependencies
- Clean up justfile test targets
- Add top-level issues, metrics, and vulnerabilities commands with SDK queries
- Add transparent token refresh in GraphQL client (removes need for auth refresh)
- Remove version, auth refresh, and auth whoami commands
- Add UserError type to skip user-correctable errors from Sentry
- Improve Sentry setup with panic recovery, release tagging
- Add YAML output format and source filter for run issues
- Auto-open browser on login instead of waiting for user input
- Update GraphQL schema to use issues instead of occurrences
- Use --version flag instead of version subcommand
- Clean up error messages and stale code
- Rename `repo` to `repository` and `runs` to `analysis`
- Rename `--run` flag to `--commit` across issues, metrics, and vulnerabilities
- Update default hostname from deepsource.io to deepsource.com
- Add `human` output format as new default, keep `table` as explicit option
- Add `--output-file`, `--verbose`, `--analyzer` filter, and `--limit` flags
- Remove legacy YAML config support and debug logging infrastructure
- Add `GetEnabledAnalyzers` API endpoint and repository analyzers command
- Fix report service using Errorf instead of Printf for info messages
- Rename "human" output format to "pretty" in issues, metrics, and vulnerabilities
- Simplify issues table: remove boxed style, drop wrapText, conditionally show SOURCE column
- Humanize displayed values (severity, status, reachability, ecosystem)
- Add ECOSYSTEM column to vulnerabilities table
- Use helper functions for formatting location, severity, and analyzer names
- Rename telemetry → sentry across adapters, interfaces, and container
- Introduce cmddeps.Deps struct for injectable config, client, and stdout
- Add NewCmd*WithDeps constructors to all commands for testability
- Add --output json flag to analysis command
- Add golden-file-based tests for analysis, issues, metrics, vulnerabilities,
  repo status, repo analyzers, and auth status commands
- Add NewWithGraphQLClient and NewTestService test helpers
- Always show auth URL in login flow regardless of browser open result
- Update justfile with new test paths
- Change table headers from ALL CAPS to Title Case across all commands
- Normalize status labels to Title Case in analysis output
- Rename default output format from "table" to "pretty", keeping "table" as alias
- Add "pretty" to shell completion candidates
- Introduce buildinfo app identity vars (AppName, ConfigDirName, KeychainSvc, KeychainKey) with prod defaults
- Override identity at startup when buildMode=dev via ldflags, giving dev builds their own binary name, config dir, and keychain entries
- Update build-and-deploy workflow to pass buildMode and use dynamic binary names per environment
- Replace hardcoded "deepsource" strings with buildinfo vars in config, keychain, and root command
- Remove shell completion generation (gen-completions.sh deleted, references stripped from workflows and Homebrew formula)
- Add just install step to CI workflow
- Rename deploy -> deploy-prod in justfile, add build alias
- Add the three info-level progress lines that the report service now
  emits (preparing, compression check, uploading)
- Update report golden file with info-level progress lines
- Fix case mismatches in OIDC tests (failed -> Failed, can not -> cannot, provider -> Provider)
- Add environment check to codesign, notarize, and verify signing steps
- Only run Apple signing workflow when building for prod
- GitHub Actions blocks job outputs that match secret values
- Move bucket resolution from resolve-env outputs to deploy step
- Reference secrets directly in deploy job based on environment
- Point dev base_url to cli.deepsource.one subdomain instead of deepsource.one/cli
- Drop cli/ key prefix for dev R2 uploads since the subdomain serves the bucket root
- Fix manifest path in install script (/manifest.json, not /build/manifest.json)
- Interactive TTY users can choose to wait for analysis or view last completed results
- Non-interactive environments auto-fallback to the last completed run
- Simplified ResolveLatestRunForBranch to delegate to resolveRunFromCommits
- Reordered issue output to show severity tag before issue text
- Added WaitOrFallback and ResolveLatestCompletedRun helpers with tests
- Removed stale reportcard-fallback test fixtures, added new status-based ones
- Set autoDetectedBranch when resolving PR for branch in issues, metrics,
  and vulnerabilities commands so auto-detected context is preserved
- Change Infof style from colored "→" prefix to plain "Note:" with a
  leading blank line for better readability
- Update tests to match new Infof format and add missing
  HasUnpushedCommitsFunc mock
- Remove analyzer name tag from issue lines, show only severity and text
- Return branch name as scope label when commit OID is empty
- Remove unused analyzerDisplayName function
- Wait for in-progress analysis runs before fetching PR issues on
  auto-detected branches
- Sort issues by severity (critical > major > minor) within each
  file group in human output
- Fix double-space between severity tag and issue text
- Skip unpushed commits warning when there are no issues to show
- Update test mock to include analysis runs query
- Show interactive scope picker (default branch / PR / commit) when no
  issues are found on the auto-detected branch, so the user can quickly
  retry without re-running the command
- Extend local-changes warning to detect uncommitted changes alongside
  unpushed commits, with distinct messages for each combination
- Add HasUncommittedChanges helper in cmdutil and wire injectable funcs
  through Deps for testability
- Fix summary line indentation in human output
- Add tests for all new paths and two new empty-response golden files
- When issues list is empty on an auto-detected branch, check if the
  latest run is still in-progress before showing the scope menu
- Catches cases where resolveIssues bypassed WaitOrFallback (e.g. PR
  path ignoring FALLBACK status)
- Interactive mode offers wait/fallback choice, non-interactive falls
  back to last completed run automatically
- Add tests for safety net in both interactive and non-interactive modes

// Mock client that returns an auth error from GetViewer
mock := graphqlclient.NewMockClient()
mock.QueryFunc = func(_ context.Context, query string, _ map[string]any, result any) error {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function parameter `result` declared but not used


The function literal assigned to mock.QueryFunc declares result as a parameter but does not use it anywhere, which can confuse maintainers and indicate incomplete refactoring or implementation.
Rename unused parameters to _ or remove them entirely if not needed to clarify intent and prevent false positive flags from static analysis.

- Switch base URL from deepsource.com/cli to cli.deepsource.com
- Generate a legacy install script for deepsource.io/cli backward compat
- Use BINDIR env var and templatize default install directory
- Remove interactive wait/poll for in-progress analysis runs
- Always fall back to last completed results with a friendlier message
- Use commit OID from resolved run in PR issues path
- Replace quoted branch name (%q) with plain "branch <name>" in warnings
- Pluralize category names in issue summary when count > 1
- Strip interactive scope menu, TTY waiting, and alternative scope prompting from issues command
- Remove --default-branch flag from report-card command
- Simplify WaitOrFallback to always fall back to last completed run
- Add in-progress run handling and local changes warnings to metrics and vulns commands
- Add output indentation for tables and Pluralize helper for footer counts
- Move golang.org/x/term to indirect dependency
- Remove unused interactive deps from cmddeps (SelectFromOptionsFunc, GetSingleLineInputFunc, IsInteractiveFunc)
- Delete orphaned golden files and related tests
- Fix os.Exit bypassing defer recovery handler in main.go
- Remove hardcoded test token from report test files
- Fix unused parameter in auth status test
- Extract ResolveAutoBranch to deduplicate branch resolution logic across issues, metrics, and vulnerabilities commands
- Extract applyLimit helper in metrics command
- Refactor reportcard test to use assertion helpers instead of compound booleans
- Extract verifyTokenWithServer helper in login command
- Fix report golden file ellipsis mismatch
- Simplify justfile test target to single go test ./... invocation
}()

exitCode := run()
os.Exit(exitCode)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`os.Exit` skips deferred function execution


The call to os.Exit(exitCode) stops all goroutines and the main program immediately without running deferred functions. This means defer statements for resource cleanup or finalization won't execute, possibly leading to resource leaks or inconsistent state.

Refactor to avoid direct os.Exit calls in functions with defer. Use return statements combined with a deferred os.Exit at a higher level to ensure defer calls run before program termination.

// used by the issues, metrics, and vulnerabilities commands. It detects the
// current branch, checks for an open PR, waits for in-progress runs, and
// handles fallback/timeout scenarios.
func ResolveAutoBranch(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High cyclomatic complexity reduces code maintainability


The function ResolveAutoBranch has a cyclomatic complexity above recommended thresholds, indicating many independent execution paths. This complexity increases the chance of bugs and makes the function difficult to maintain or test.

Refactor ResolveAutoBranch by splitting into smaller functions or simplifying control flow. This reduces complexity and improves code clarity and testability.

Comment on lines +151 to +153
if err != nil {
return
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error from `deepsource.New` is silently ignored during token verification


The error returned by deepsource.New is not handled. If client instantiation fails due to a misconfiguration or network issue, the token verification process is silently aborted, and the application continues assuming the token is valid. This can mask underlying problems and lead to confusing errors later.

Consider treating a client creation failure as a token verification failure by setting opts.TokenExpired = true. This would force a re-login, allowing the user to correct the configuration.

}()

exitCode := run()
os.Exit(exitCode)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`os.Exit` skips deferred calls, causing resource leaks


Using os.Exit directly in a function with deferred calls prevents execution of those deferred calls, leading to unclosed resources or incomplete cleanup steps. This abrupt termination skips all deferred functions concluding the program instantly.

Replace direct calls to os.Exit with structured returns and a top-level deferred os.Exit or handle cleanup explicitly before exiting to ensure all deferred functions run.

// used by the issues, metrics, and vulnerabilities commands. It detects the
// current branch, checks for an open PR, waits for in-progress runs, and
// handles fallback/timeout scenarios.
func ResolveAutoBranch(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function `ResolveAutoBranch` has excessive decision points


The ResolveAutoBranch function has high cyclomatic complexity, indicating numerous decision points and independent paths. This complexity increases the risk of bugs and makes the function harder to understand and maintain.

Break down ResolveAutoBranch into smaller, simpler functions or refactor complex control flow to reduce complexity and improve code clarity and testability.

Comment on lines 266 to 269
if runErr == nil {
result.CommitOid = run.CommitOid
}
return result, nil
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error `runErr` from `ResolveLatestRunForBranch` is ignored


In the pull request resolution path, if ResolveLatestRunForBranch returns an error, it is effectively ignored. The function proceeds to return a nil error with a result where CommitOid is not set, which can lead to unexpected behavior in the calling commands that might assume CommitOid is always present if a PR is found.

The error runErr should be checked immediately after the call to ResolveLatestRunForBranch and propagated to the caller to ensure robust error handling.

- Use dynamic base URL for legacy install script instead of hardcoded deepsource.io/cli
- Remove prod/dev prefix branching in R2 upload, always use empty prefix
- Extract mainRun() with named return so defer handles panic exit code without calling os.Exit in deferred func
- Split ResolveAutoBranch into resolveWithPR/resolveWithoutPR helpers
- Handle os.Setenv/os.Unsetenv errors in report test setup
- Add unit tests for detectProvider, extractRepoName, extractOwner, extractADSOwner
- Add GitLab, Bitbucket, and unsupported provider cases for GetRemoteMap
- Add tests for testutil helpers (LoadGoldenFile, MockQueryFunc, CreateTestConfigManager)
- Replace hardcoded "deepsource" with resolve-env binary_name output
- Keeps legacy install script consistent with the rest of the workflow
- Prefix "branch " to scope labels in issues, metrics, reportcard, and
  vulnerabilities commands so output reads "branch main" instead of "main"
- Switch deploy tags from annotated (-a) to signed (-s) in justfile
- Homebrew formula generation and push to homebrew-cli repo no longer needed
jai-deepsource
jai-deepsource previously approved these changes Feb 26, 2026
Signed-off-by: Jai Pradeesh <jai@deepsource.io>
- Add detailed usage, flags, and examples to the root cobra command using heredoc
- Replace manual CODE_PATH env save/restore with t.Setenv in report tests
- Add report service tests: no-compression, server error, HTTP error, cert skip, sentry capture
- Add edge case tests for ADS/SSH owner extraction in remotes_test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants